package cn.edu.lingnan.before.serviceimpl;

import cn.edu.lingnan.before.mapper.UserMapper;
import cn.edu.lingnan.before.pojo.User;
import cn.edu.lingnan.before.serivce.UserService;
import cn.edu.lingnan.common.Email;
import cn.edu.lingnan.common.JSONResult;
import cn.edu.lingnan.common.TimeKeep;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.bouncycastle.jcajce.provider.digest.MD5;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.UUID;

@Service
public class UserServiceImpl implements UserService {
    //注入持久层对象到业务中使用
    @Resource
    private UserMapper userMapper;

    @Override
    public JSONResult<Void> checkEmailService(String email) {
        // 对参数判断
        if("".equals(email) || email == null)
        {
            return new JSONResult<>(201,"邮箱不能为空");
        }
        // 判断邮箱的格式是否正确 QQ邮箱
        //qq邮箱的正则表达式
        String regex6 = "[1-9]\\d{7,10}@qq\\.com";
        if( !email.matches(regex6))
        {
            return new JSONResult<>(201,"邮箱格式错误");
        }
        // 判断该邮箱是否存在
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_email",email);
        User user = userMapper.selectOne(wrapper);
        if(user != null)
        {
            return new JSONResult<>(203,"该邮箱已被注册");
        }
        return new JSONResult<>(200,"邮箱验证通过");
    }

    @Override
    public JSONResult<Void> checkPasswordAndConfirmPwd(String password, String confirmPwd) {
        //非空判断
        if("".equals(password) || password==null)
        {
            return new JSONResult<>(201,"密码不能为空");
        }
        if("".equals(confirmPwd) || confirmPwd==null)
        {
            return new JSONResult<>(202,"确认密码不能为空");
        }
        //一致性判断
        if(!password.equals(confirmPwd))
        {
            return new JSONResult<>(203,"两次密码不一致");
        }

        return new JSONResult<>(200,"OK");
    }

    @Override
    public JSONResult<Void> sendEmail(String email, HttpSession session) {
        /*
        * 进行参数判断
        * 调用已有的方法进行判断，非空，邮箱格式，是否存在数据库中
        * */
        JSONResult<Void> jsonResult = checkEmailService(email);
        if(jsonResult.getCode() != 200)
        {
            return jsonResult;
        }

        String s = Email.sendEmail(email);
        if(s == null)
        {
            return new JSONResult<>(203,"邮件发送失败");
        }
        TimeKeep timeKeep = new TimeKeep(session);
        Thread thread = new Thread(timeKeep);
        thread.start();
        session.setAttribute("email",s);
        return new JSONResult<>(200,"发送成功");
    }

    @Override
    public JSONResult<Void> checkEmailCode(String emailCode, HttpSession session) {
        if(emailCode == null || "".equals(emailCode))
        {
            return new JSONResult<>(203,"验证码不能为空");
        }
        Object email = session.getAttribute("email");
        if(email == null)
        {
            return new JSONResult<>(201,"验证码超时或未发送验证码");
        }
        if(!email.equals(emailCode))
        {
            return new JSONResult<>(202,"验证码错误，请重新输入");
        }
        return new JSONResult<>(200,"验证通过");
    }

    @Override
    public JSONResult<Void> doReg(String email, String password, String confirmPwd, String emailCode,HttpSession session) {
        // 验证邮箱
        JSONResult<Void> emailResult = checkEmailService(email);
        if(emailResult.getCode() != 200)
        {
            return emailResult;
        }
        // 验证密码
        JSONResult<Void> passResult = checkPasswordAndConfirmPwd(password, confirmPwd);
        if(passResult.getCode() != 200)
        {
            return passResult;
        }
        //验证 邮箱验证码
        JSONResult<Void> emailCodeResult = checkEmailCode(emailCode, session);
        if(emailCodeResult.getCode() != 200 )
        {
            return emailCodeResult;
        }
        // 密码加密 生成盐
        String salt = UUID.randomUUID().toString(); //36 位字符串
        String md5Password = md5Password(password, salt);//加密后的密码
//        封装数据到对象中
        User user = new User().setUserEmail(email).setPassword(md5Password).setSalt(salt)
                .setCreateTime(new Date()).setIsDelete(1);
        // 添加数据
        int row = userMapper.insert(user);
        if(row != 1)
        {
            return new JSONResult<>(207,"注册失败，稍后重试");
        }
        return new JSONResult<>(200,"注册成功");
    }

    @Override
    public JSONResult<Void> checkLoginEmail(String email) {

        // 对参数非空判断
        if("".equals(email) || email == null)
        {
            return new JSONResult<>(201,"登录邮箱不能为空");
        }
        // 判断邮箱的格式是否正确 QQ邮箱
        //qq邮箱的正则表达式
        String regex6 = "[1-9]\\d{7,10}@qq\\.com";
        if( !email.matches(regex6))
        {
            return new JSONResult<>(201,"登录邮箱格式错误");
        }
        // 判断该邮箱是否存在于数据库
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_email",email);
        User user = userMapper.selectOne(wrapper);
        if(user == null)
        {
            return new JSONResult<>(203,"登录邮箱未注册");
        }
        return new JSONResult<>(200,"√");
    }

    @Override
    public JSONResult<Void> doLogin(String email, String password, String code, HttpSession session) {
        //检查邮箱
        JSONResult<Void> loginEmail = checkLoginEmail(email);
        if(loginEmail.getCode() != 200)
        {
            return loginEmail;
        }
        //密码非空判断
        if(password == null || "".equals(password))
        {
            return new JSONResult<>(201,"登录密码必填");
        }
        //检查密码是否正确
        /*
            根据email 查询当前数据
            获取加密后的密码和注册时使用的盐
         */
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_email",email);
        User user = userMapper.selectOne(queryWrapper);
        if(user == null)
        {
            return new JSONResult<>(502,"该数据可能被删除");
        }
        String regMD5Pwd = user.getPassword();
        String salt = user.getSalt();
        String md5Password = md5Password(password, salt);
        if(!regMD5Pwd.equals(md5Password))
        {
            return new JSONResult<>(503,"密码错误");
        }
        //判断code
        if(code == null ||"".equals(code))
        {
            return new JSONResult<>(203,"验证码不能为空");
        }
        String loginCode = (String)session.getAttribute("loginCode");
        if(loginCode == null)
        {
            return new JSONResult<>(204,"验证码失效");
        }
        if(!loginCode.equals(code.toUpperCase()))
        {
            return new JSONResult<>(205,"验证码错误");
        }
//        验证成功，绑定用户数据
        session.setAttribute("user",user);
        return new JSONResult<>(200,"登录验证成功");
    }

    // 封装一个方法用于密码加密使用
    public String md5Password(String password,String salt){
        String md5Pwd = password + salt;
        /*
        * 调用API加密
        * */
        byte[] bytes = md5Pwd.getBytes();
        String s = "";
        // 加密10次
        for (int i = 0; i < 10; i++) {
            s = DigestUtils.md5DigestAsHex(md5Pwd.getBytes());
        }

        return s;
    }




}
